package com.spark.concurrency.thread.method;

import java.util.Date;
import java.util.concurrent.locks.Lock;

/**
 * 一个线程被唤醒可能有一下四种情况
 * 其它的线程调用 obj.notify()，且当前线程 T，正好是被选中唤醒的。
 * 其它的线程调用 obj.notifyAll()。
 * 其它线程中断 T。
 * 指定的等待时间（timeout）超时，（时间精度会有些误差）。
 * 但我想说一下一个完整的过程是，唤醒之后需要去抢到临界区的锁，才能真正把代码执行下去，光有唤醒是不够的
 */
public class WaitTest2 {
    public static void main(String[] args) {
        ThreadA t1 = new ThreadA("t1");
        System.out.println("1、t1:" + t1);
        synchronized (t1) {
            try {
                //启动线程
                System.out.println("2、" + Thread.currentThread().getName() + " start t1");
                t1.start();
                //主线程等待t1通过notify唤醒。
                System.out.println("3、" + Thread.currentThread().getName() + " wait()" + new Date());
                t1.wait();// 不是使t1线程等待，而是当前执行wait的线程等待
                System.out.println("6、" + Thread.currentThread().getName() + " continue" + new Date());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

class ThreadA extends Thread {
    public ThreadA(String name) {
        super(name);
    }

    @Override
    public void run() {
        synchronized (this) {
            System.out.println("4、this:" + this);
            try {
                Thread.sleep(2000);//使当前线程阻塞1秒
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("5、" + Thread.currentThread().getName() + " call notify()");
            this.notify();
        }
    }
}
